
/*************
author:: libo
license:: MIT
*****************/

#include<tool/libcell_octree_iterator.h>
#include<thread>

Octree_Trav octree_begin(OC_Node* ocn)
{
    Octree_Trav oct;
    Octree_Trav_init(&oct);
    oct.tree=ocn;
    OC_Node* it=ocn;
    while(it->children[0]!=NULL)
    {
        it=it->children[0];
    } 
    oct.it=it;

    return oct;  
}
Octree_Trav octree_end(OC_Node*ocn)
{
    Octree_Trav oct;
    Octree_Trav_init(&oct);

    oct.tree=ocn;

    return  oct;
}
Octree_Trav operator++(Octree_Trav& trav)
{
    if(trav.it==NULL)
    {
        return trav;
    }
    OC_Node* it=trav.it;
    while(it->parent!=NULL&&it->parent->children[7]==it)
    {
        it=it->parent;
    } 
    if(it->parent==NULL)
    {
        trav.it=NULL;
    }
    else
    {
        for(int i=0;i<8;i++)
        {
            if(it->parent->children[i]==it)
            {
                it=it->parent->children[i+1];
                break;
            }
        }
        while(it->children[0]!=NULL)
        {
            it=it->children[0];
        } 
        trav.it=it;
    }
    return trav;

}

Octree_Trav operator++(Octree_Trav& trav,int)
{
    if(trav.it==NULL)
    {
        return trav;
    }
    Octree_Trav trav1=trav;
    OC_Node* it=trav.it;
    while(it->parent!=NULL&&it->parent->children[7]==it)
    {
        it=it->parent;
    } 
    if(it->parent==NULL)
    {
        trav.it=NULL;
    }
    else
    {
        for(int i=0;i<8;i++)
        {
            if(it->parent->children[i]==it)
            {
                it=it->parent->children[i+1];
                break;
            }
        }
        while(it->children[0]!=NULL)
        {
            it=it->children[0];
        } 
        trav.it=it;

    }
    return trav1;
}
static inline void oc_node_divide_all_leavest(OC_Node* ocn,int *count)
{
    *count=oc_node_divide_all_leaves(ocn);
}


//加入线程

int oc_node_divide_all_leavesp(OC_Node* ocn)
{
    int re=0;
    if(ocn==NULL)
    {return re;}
    if(ocn->children[0]==NULL)
    {
        return (ocn->value==NULL?0:oc_node_divide_one_leaf(ocn));
    }

    int counts[8]={0};
    std::thread mythread0(oc_node_divide_all_leavest,ocn->children[0],&(counts[0]));
    std::thread mythread1(oc_node_divide_all_leavest,ocn->children[1],&(counts[1]));
    std::thread mythread2(oc_node_divide_all_leavest,ocn->children[2],&(counts[2]));
    std::thread mythread3(oc_node_divide_all_leavest,ocn->children[3],&(counts[3]));
    std::thread mythread4(oc_node_divide_all_leavest,ocn->children[4],&(counts[4]));
    std::thread mythread5(oc_node_divide_all_leavest,ocn->children[5],&(counts[5]));
    std::thread mythread6(oc_node_divide_all_leavest,ocn->children[6],&(counts[6]));
    std::thread mythread7(oc_node_divide_all_leavest,ocn->children[7],&(counts[7]));


    mythread0.join();
    mythread1.join();
    mythread2.join();
    mythread3.join();
    mythread4.join();
    mythread5.join();
    mythread6.join();
    mythread7.join();
    for(int i=0;i<8;i++)
    {
        re+=counts[i];
    }
    return re;  

}
bool operator!=(const Octree_Trav&trav1,const Octree_Trav&trav2)
{
    if(trav1.tree!=trav2.tree)
    {
        return true;
    }
    if(trav1.it!=trav2.it)
    {
        return true;
    }
    return false;
}

